package com.novel.framework.utils.file;


import com.novel.common.exception.file.FileNameLengthLimitExceededException;
import com.novel.common.exception.file.FileSizeLimitExceededException;
import com.novel.common.exception.file.InvalidExtensionException;
import com.novel.common.resource.IResourceService;
import com.novel.framework.utils.config.Global;
import com.novel.framework.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Objects;

/**
 * 文件上传工具类
 *
 * @author novel
 * @date 2019/5/24
 */
@Slf4j
public class FileUploadUtils {
    /**
     * 默认大小 50M
     */
    private static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;

    /**
     * 默认的文件名最大长度 100
     */
    private static final int DEFAULT_FILE_NAME_LENGTH = 100;

    /**
     * 默认上传的地址
     */
    private static String defaultBaseDir = Global.getProfile();

    private static IResourceService resourceService;


    static {
        if (Boolean.parseBoolean(Global.getConfig("resource.enable"))) {
            try {
                resourceService = SpringUtils.getBean(IResourceService.class);
            } catch (Exception e) {
                log.error("获取IResourceService服务失败,{}", e.getMessage());
            }
        }
    }

    public static void setDefaultBaseDir(String defaultBaseDir) {
        FileUploadUtils.defaultBaseDir = defaultBaseDir;
    }

    public static String getDefaultBaseDir() {
        return defaultBaseDir;
    }

    /**
     * 以默认配置进行文件上传
     *
     * @param file 上传的文件
     * @return 文件名称
     * @throws IOException
     */
    public static String upload(MultipartFile file) throws IOException {
        try {
            return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
        } catch (Exception e) {
            throw new IOException(e.getMessage(), e);
        }
    }

    /**
     * 根据文件路径上传
     *
     * @param baseDir 相对应用的基目录
     * @param file    上传的文件
     * @return 文件名称
     * @throws IOException
     */
    public static String upload(String baseDir, MultipartFile file) throws IOException {
        try {
            return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
        } catch (Exception e) {
            throw new IOException(e.getMessage(), e);
        }
    }

    /**
     * 文件上传
     *
     * @param baseDir 相对应用的基目录
     * @param file    上传的文件
     * @return 返回上传成功的文件名
     * @throws FileSizeLimitExceededException       如果超出最大大小
     * @throws FileNameLengthLimitExceededException 文件名太长
     * @throws IOException                          比如读写文件出错时
     * @throws InvalidExtensionException            文件校验异常
     */
    public static String upload(String baseDir, MultipartFile file, String[] allowedExtension) throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, InvalidExtensionException {
        int fileNameLength = Objects.requireNonNull(file.getOriginalFilename()).length();
        if (fileNameLength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) {
            throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
        }
        FileUtils.assertAllowed(file, allowedExtension, DEFAULT_MAX_SIZE);
        String fileName = FileUtils.extractFilename(file);
        if (Boolean.parseBoolean(Global.getConfig("resource.enable")) && resourceService != null) {
            resourceService.upLoadFile(file.getInputStream(), fileName);
            if (Boolean.parseBoolean(Global.getConfig("resource.cache-enable"))) {
                File desc = FileUtils.getAbsoluteFile(baseDir, fileName);
                file.transferTo(desc);
            }
        } else {
            File desc = FileUtils.getAbsoluteFile(baseDir, fileName);
            file.transferTo(desc);
        }
        return fileName;
    }
}